import React, { memo, forwardRef, useRef, useState, useMemo, useEffect } from 'react';
import _ from 'lodash';
import { Button, Input, Select, Form } from 'antd';
import { RouteContext } from '@ant-design/pro-layout';
import { DownOutlined, SearchOutlined, SettingOutlined, UpOutlined } from '@ant-design/icons';
import styles from './index.less';

const limitMinWidth = 240;
const AntDesignFormControls = { Input, Select };

const SearchItems = ({ formList, maxColNum, barCollapsed, setBarCollapsed }) => {
  const widthPercent = Math.floor((100 / maxColNum) * 10) / 10;

  return (
    <div className={styles.searchBarContent}>
      {formList.map(
        (item, index) =>
          item.Component && (
            <div
              key={`search-form-${item.key}-${item.searchType}`}
              className={styles.searchItem}
              style={
                barCollapsed
                  ? index < maxColNum - 1
                    ? { width: `${widthPercent}%` }
                    : { display: 'none' }
                  : { width: `${widthPercent}%` }
              }
            >
              <Form.Item key={`${item.key}-${item.searchType}`} name={item.key} {...item.props}>
                {React.createElement(AntDesignFormControls[item.Component], {
                  ...(item.componentProps || {}),
                })}
              </Form.Item>
            </div>
          ),
      )}
      <div className={styles.searchEmptyItem} style={{ width: `${widthPercent}%` }} />
      <div className={styles.actionButton}>
        <Button ghost type="primary" icon={<SettingOutlined />} className={styles.actionButtonItem}>
          重置
        </Button>
        <Button type="primary" icon={<SearchOutlined />} className={styles.actionButtonItem}>
          查询
        </Button>
        <span
          className={styles.toggleButtonItem}
          style={maxColNum <= formList.length ? {} : { display: 'none' }}
          onClick={() => {
            setBarCollapsed((status) => !status);
          }}
        >
          {barCollapsed ? <DownOutlined /> : <UpOutlined />}
          {barCollapsed ? '展开' : '收起'}
        </span>
      </div>
    </div>
  );
};

const SearchBar = memo(
  ({ formList = [], isMobile, collapsed, containerWidth, menuRender }) => {
    const barContainerRef = useRef(null);
    const [contentWidth, setContentWidth] = useState(0);
    const [barCollapsed, setBarCollapsed] = useState(true);

    // 最大列数
    const maxColNum = useMemo(
      () => _.max([Math.floor((contentWidth - 20 * 2) / limitMinWidth), 1]),
      [contentWidth],
    );

    // 宽度计算
    const adaptWidth = () => {
      const currentContentWidth = barContainerRef.current?.clientWidth || containerWidth;
      setContentWidth(currentContentWidth);
      return currentContentWidth;
    };
    const adaptContentWidth = _.throttle(adaptWidth, 500);

    // 初始化
    useEffect(() => {
      setTimeout(() => {
        adaptContentWidth();
      }, 300);
    }, [isMobile, collapsed, menuRender]);
    useEffect(() => {
      // 计算宽度
      const defaultContentWidth = adaptContentWidth();
      window.addEventListener('resize', adaptContentWidth);
      // 初始化时，若最多展示1列的情况下， 设置为默认展开
      const defaultMaxColNum = _.max([
        Math.floor((defaultContentWidth - 20 * 2) / limitMinWidth),
        1,
      ]);
      setBarCollapsed(defaultMaxColNum !== 1);
      return () => {
        window.removeEventListener('resize', adaptContentWidth, false);
      };
    }, []);

    return (
      <div
        ref={barContainerRef}
        className={styles.searchBar}
        style={{
          height: `${
            24 + 56 * (barCollapsed ? 1 : Math.ceil((formList.length + 1) / maxColNum))
          }px`,
        }}
      >
        <SearchItems
          formList={formList}
          maxColNum={maxColNum}
          barCollapsed={barCollapsed}
          setBarCollapsed={setBarCollapsed}
        />
      </div>
    );
  },
  (prevProps, nextProps) =>
    prevProps.formList === nextProps.formList &&
    prevProps.isMobile === nextProps.isMobile &&
    prevProps.collapsed === nextProps.collapsed &&
    prevProps.menuRender === nextProps.menuRender,
);

export default forwardRef((props, ref) => (
  <RouteContext.Consumer>
    {(partial) => {
      const { isMobile, collapsed, layout, menuRender, siderWidth } = partial || {};
      const defaultContainerWidth =
        document.body.clientWidth -
        20 * 2 -
        386 -
        (isMobile || layout === 'top' || !menuRender ? 0 : collapsed ? 60 : siderWidth);
      return (
        <SearchBar
          ref={ref}
          {...props}
          isMobile={isMobile}
          collapsed={collapsed}
          menuRender={layout === 'top' ? false : !!menuRender}
          containerWidth={_.max([defaultContainerWidth, 606])}
        />
      );
    }}
  </RouteContext.Consumer>
));
